package webgamemaker.Editor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import webgamemaker.Common.Callback;
import webgamemaker.Common.ExtendedGWTCanvas;
import webgamemaker.Common.TileSet;


import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.MouseDownEvent;
import com.smartgwt.client.widgets.events.MouseDownHandler;
import com.smartgwt.client.widgets.events.MouseMoveEvent;
import com.smartgwt.client.widgets.events.MouseMoveHandler;
import com.smartgwt.client.widgets.events.MouseUpEvent;
import com.smartgwt.client.widgets.events.MouseUpHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.HStack;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.layout.VStack;


public class TileSetPicker extends Canvas
{
	public GWTCanvas canvas, frontCanvas;
	public ExtendedGWTCanvas defaultLayerTextCanvas;
	public Canvas container;
	public TileSet tileset;
	public int nbTilePerLine = 8;
	public int width, height;
	public boolean mouseDown;
	public int startX, startY;
	public int endX, endY;
	public int selectX1, selectY1, selectX2, selectY2;
	public boolean drawDefaultLayer;
	public ArrayList<Callback> selectCallback;
	
	public TileSetPicker(TileSet tileset)
	{
		resetCanvas();
		this.tileset = tileset;
		selectX1 = selectY1 = selectX2 = selectY2 = -1;
		selectCallback = new ArrayList<Callback>();
		//DOM.setCapture(getElement());
		tileset.addLoadCallback(new Callback()
			{
				public void onCall(Object obj) 
				{
					redraw();
				}
			});
		this.addMouseUpHandler(new MouseUpHandler()
		{
			public void onMouseUp(MouseUpEvent event) 
			{
				mouseDown = false;
				for(int i = 0; i < selectCallback.size(); i++)
					selectCallback.get(i).onCall(TileSetPicker.this);
			}
			
		});
		this.addMouseDownHandler(new MouseDownHandler()
		{
			public void onMouseDown(MouseDownEvent event) 
			{
				mouseDown = true;
				startX = (event.getX()-TileSetPicker.this.getAbsoluteLeft())/TileSetPicker.this.tileset.tileWidth;
				startY = (event.getY()-TileSetPicker.this.getAbsoluteTop())/TileSetPicker.this.tileset.tileHeight;
				endX = startX;
				endY = startY;
				selectX1 = selectX2 = startX;
				selectY1 = selectY2 = startY;
				drawFrontCanvas();
			}
			
		});
		this.addMouseMoveHandler(new MouseMoveHandler()
		{
			public void onMouseMove(MouseMoveEvent event) 
			{
				if(mouseDown)
				{
					endX = (event.getX()-TileSetPicker.this.getAbsoluteLeft())/TileSetPicker.this.tileset.tileWidth;
					endY = (event.getY()-TileSetPicker.this.getAbsoluteTop())/TileSetPicker.this.tileset.tileHeight;
					selectX1 = Math.min(startX,endX);
					selectY1 = Math.min(startY,endY);
					selectX2 = Math.max(startX,endX);
					selectY2 = Math.max(startY,endY);
					drawFrontCanvas();	
				}
			}
		});
	}
	
	public void addSelectCallback(Callback callback)
	{
		selectCallback.add(callback);
	}
	
	public void resetCanvas()
	{
		canvas = new GWTCanvas();
		frontCanvas = new GWTCanvas();
		defaultLayerTextCanvas = new ExtendedGWTCanvas();
		if(container != null)
		{
			removeChild(container);
			redraw();
		}
		container = new Canvas();
		container.addChild(canvas);
		container.addChild(frontCanvas);
		container.addChild(defaultLayerTextCanvas);
		addChild(container);
	}
	
	public void redraw()
	{
		width = tileset.tileWidth*nbTilePerLine;
		height = tileset.tileHeight*(int)Math.ceil((double)tileset.tiles.size()/nbTilePerLine);
		canvas.resize(width, height);
		frontCanvas.resize(width, height);
		defaultLayerTextCanvas.resize(width, height);
		/*this.setSize(width+"px", height+"px");
		this.setPixelWidth(width);
		this.setPixelHeight(height);
		this.setCoordWidth(width);
		this.setCoordHeight(height+100);*/
		drawCanvas();
		drawFrontCanvas();
		drawDefaultLayerText();
	}
	
	public void drawDefaultLayerText()
	{
		defaultLayerTextCanvas.clear();
		if(drawDefaultLayer && defaultLayerTextCanvas.hasText())
		{
			defaultLayerTextCanvas.setFont("bold 15px Helvetica, Arial");
			defaultLayerTextCanvas.setShadowColor("rgb(255,255,255)");
			//defaultLayerTextCanvas.setShadowOffset(-1,-1);
			defaultLayerTextCanvas.setShadowBlur(2);
			int tileWidth = tileset.tileWidth, tileHeight = tileset.tileHeight;
			int x = tileWidth/2, y = tileHeight/2;
			for(int i = 0; i < tileset.tiles.size(); i++)
			{
				if(x > width)
				{
					x = tileWidth/2;
					y += tileset.tileHeight;
				}
				defaultLayerTextCanvas.fillText(""+tileset.tiles.get(i).default_layer, x, y);
				x += tileset.tileWidth;
			}
		}
	}
	
	public void drawCanvas()
	{
		canvas.clear();
		int width = canvas.getCoordWidth();
		int height = canvas.getCoordHeight();
		if(tileset.loaded)
		{
			int x = 0, y = 0;
			int tileWidth = tileset.tileWidth, tileHeight = tileset.tileHeight;
			Map<String,Object> param = new HashMap<String,Object>();
			param.put("context", canvas);
			boolean neighbour[] = new boolean[8];
			param.put("neighbour", neighbour);
			for(int i = 0; i < tileset.tiles.size(); i++)
			{
				if(x+tileset.tileWidth > width)
				{
					x = 0;
					y += tileset.tileHeight;
				}
				//if(y+tileset.tileHeight > height)
					//break;
				param.put("x", x);
				param.put("y", y);
				tileset.tiles.get(i).tile.draw(param);
				x += tileset.tileWidth;
			}
		}
	}
	
	public void drawFrontCanvas()
	{
		frontCanvas.clear();
		int tileWidth = tileset.tileWidth, tileHeight = tileset.tileHeight;
		if(selectX1 != -1)
		{
			frontCanvas.saveContext();
			frontCanvas.setLineWidth(2.0);
			frontCanvas.strokeRect(selectX1*tileWidth,selectY1*tileHeight, (selectX2-selectX1+1)*tileWidth, (selectY2-selectY1+1)*tileHeight);
			frontCanvas.restoreContext();
		}
	}
}
